#include <stdio.h>
#include "unistd.h"
#include "stdlib.h"
#include "sys/types.h"
#include "sys/wait.h"
#include "string.h"
#include "sys/mman.h"
#include "fcntl.h"
#include "semaphore.h"

int main(int argc, char const *argv[])
{
    // 打开共享内存
    int fd = shm_open("my_shm", O_RDWR | O_CREAT, 0666);
    if (fd == -1)
    {
        perror("shm_open失败");
        exit(EXIT_FAILURE);
    }

    // 给共享内存分配大小
    int r = ftruncate(fd, 1024);
    if (r == -1)
    {
        perror("ftruncate失败");
        exit(EXIT_FAILURE);
    }

    // 映射共享内存
    char *p = (char *)mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (p == MAP_FAILED)
    {
        perror("mmap失败");
        exit(EXIT_FAILURE);
    }

    int pid = fork();
    if (pid == -1)
    {
        perror("进程fork失败");
    }
    else if (pid > 0)
    {
        sleep(5);
        // 父进程向共享内存写数据
        strcpy(p, "hello abc");

        // 参数1: 信号量的名字 /开头 参数2:打开方式 串讲 参数3:信号量的权限 参数4:信号量的初始化
        sem_t *sem = sem_open("/sem", O_CREAT, 0666, 0);
        // 增加信号量
        sem_post(sem);

        waitpid(pid, NULL, 0);

        munmap(p, 1024); // 释放内存
        close(fd);
        shm_unlink("my_shm");
    }
    else if (pid == 0)
    {
        // 等待信号量
        sem_t *sem = sem_open("/sem", O_RDONLY);
        sem_wait(sem);
        printf("等到信号量\r\n");

        printf("%s\n", p);
    }

    return 0;
}
